﻿using HalconDotNet;
using HWindow_Tool.Control;
using LD.Host;
using Newtonsoft.Json.Linq;
using ReaLTaiizor.Extension;
using SqlSugar;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.UI;
using System.Windows.Forms;
using System.Xml;
using ViewWindow.Config;
using ViewWindow.Model;
using YTE.Control;
using 右下角弹窗.DiagShow;

namespace LD.Vision
{
    public partial class FrmTemplate : FrmBase
    {
        private HWindow_Final hWindow = null;
        private TemplateModel template;
        private bool draw = false;//是否要绘制
        private int style = 0;//要绘制的类型0--直线，1圆，2，矩形，3，角度矩形，4，扇形
        public FrmTemplate()
        {
            InitializeComponent();
            this.Shown += FrmCam_Shown;
        }
        private void FrmCam_Shown(object sender, EventArgs e)
        {
            if (template == null)
                template = new TemplateModel();

            if (hWindow == null)
            {
                hWindow = new HWindow_Final();
                hWindow.Dock = DockStyle.Fill;
                hWindow.hWindowControl.MouseDown += HWindow_MouseClick;
                this.splitContainer1.Panel1.Controls.Add(hWindow);
            }
        }
        private void HWindow_MouseClick(object sender, MouseEventArgs e)
        {
            int index;

            List<HTuple> data;
            ViewWindow.Model.ROI roi = hWindow.viewWindow.smallestActiveROI(out data, out index);//可以获取最后一次选中或者编辑对象的数据

            if (index > -1)
            {
                string name = roi.GetType().Name;//得到最后一次选中的对象名字
                //this.template.Roi[index] = roi;//这里更新了数据---这句话非常重要
            }

            if (draw == false) return;
            hWindow.hWindowControl.HalconWindow.GetMposition(out int y, out int x, out int b);

            //  this.Text = b.ToString();
            if (b == 4)
            {
                draw = false;
                CreateTmplate();
                return;//按下的是右键
            }
            var _roi = this.template.RoiTmp;
            switch (style)
            {
                case 0://dian
                    hWindow.viewWindow.genPoint(y, x, ref _roi);
                    break;

                case 1://直线
                    hWindow.viewWindow.genLine(y, x - 20, y, x + 20, ref _roi);
                    break;

                case 2://圆
                    hWindow.viewWindow.genCircle(y, x, 60.0, ref _roi);
                    break;
                case 3://矩形
                    hWindow.viewWindow.genRect1(y - 50, x - 50, y + 50, x + 50, ref _roi);
                    break;
                case 4://角度矩形
                    hWindow.viewWindow.genRect2(y, x, 30.0 / 180.0 * Math.PI, 60.0, 30.0, ref _roi);
                    break;
                case 5://扇形
                    hWindow.viewWindow.genCircularArc(y, x, 40.0, 0, -3.14, "negative", ref _roi);
                    break;
                default:
                    draw = false;//退出
                    return;
            }
            this.template.RoiTmp = _roi;
            draw = false;
        }
        private HImage hImage;
        public HImage HImage
        {
            get { return hImage; }
            set
            {
                hImage = value;
                this.hWindow.Image = value;
            }
        }
        public TemplateModel TemplateModel
        {
            get
            {
                return template;
            }
            set
            {
                template = value;
                if (template == null)
                    template = new TemplateModel();
                else
                {
                    this.num_minScore.Value = this.template.Param.MinScore.ObjToDecimal();                      //最小分数
                    this.num_matchNum.Value = this.template.Param.NumMatches;                    //匹配个数
                    this.num_maxOverlap.Value = (decimal)this.template.Param.MaxOverlap;         //重叠部分
                    this.num_rad1.Value = this.template.Param.StartRad.ObjToDecimal();                          //角度
                    this.num_rad2.Value = this.template.Param.EndRad.ObjToDecimal();                            //角度
                    this.cob_jixing.Text = this.template.Param.Polarity;                         //极性"use_polarity" : "ignore_global_polarity";  //

                    try
                    {
                        //展示roi
                        List<ROI> roiList=new List<ROI>();
                        this.hWindow.viewWindow.loadROI(template.RoiXmlPath, out roiList);
                        hWindow.viewWindow.displayROI(roiList);
                        List<ROI> roiTmpList=new List<ROI>();
                        this.hWindow.viewWindow.loadROI(template.RoiTmpXmlPath, out roiTmpList);
                        hWindow.viewWindow.displayROI(roiTmpList);
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }
        public string FilePathByRoi
        {
            get; set;
        }
        public string FilePathByRoiTmp
        {
            get; set;
        }
        public void LoadTemplate(string filePath)
        {
            try
            {
                template.Load(filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void Save()
        {
            try
            {
                //另存为
                using (SaveFileDialog sfd = new SaveFileDialog())
                {
                    sfd.Filter = "Ldm|*.ldm";
                    sfd.RestoreDirectory = true;
                    sfd.CheckPathExists = true;
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        string fileName = sfd.FileName;
                        template.Save(fileName);
                    }
                }

                Log4.Info("保存成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        public void SaveRoi()
        {
            //保存roi
            this.hWindow.viewWindow.saveROI(this.template.RoiTmp, this.template.RoiTmpXmlPath);
            this.hWindow.viewWindow.saveROI(this.template.Roi, this.template.RoiXmlPath);
        }
        private void btn_deleteRoi_Click(object sender, EventArgs e)
        {
            if (template.Roi.Count == 0)
                return;
            var roi = template.Roi;
            hWindow.viewWindow.removeActiveROI(ref roi);
        }
        private void tsb_roi矩形_Click(object sender, EventArgs e)
        {
            //暂时只是支持一个roi
            this.template.Roi.Clear();
            var roi = this.template.Roi;
            hWindow.viewWindow.genRect1(110.0, 110.0, 210.0, 210.0, ref roi);
            this.template.Roi = roi;
            this.template.Roi.Last().Color = "orange";
        }
        private void tsb_圆_Click(object sender, EventArgs e)
        {
            this.template.RoiTmp.Clear();
            var roi = this.template.RoiTmp;
            hWindow.viewWindow.genCircle(200.0, 200.0, 60.0, ref roi);
            this.template.RoiTmp = roi;
            this.template.RoiTmp.Last().Color = "blue";
            this.hWindow.viewWindow.saveROI(roi, Application.StartupPath + "\\view.xlm");
        }
        private void tsb_矩形_Click(object sender, EventArgs e)
        {
            this.template.RoiTmp.Clear();
            draw = true;
            style = 3;
            //var roi = this.template.TmpRoi;
            //hWindow.viewWindow.genRect1(110.0, 110.0, 210.0, 210.0, ref roi);
            //this.template.TmpRoi = roi;
            //this.template.TmpRoi.Last().Color = "blue";
        }
        private void tsb_多边形_Click(object sender, EventArgs e)
        {
            this.template.RoiTmp.Clear();
        }
        private void tsb_矩形2_Click(object sender, EventArgs e)
        {
            this.template.RoiTmp.Clear();
            var roi = this.template.RoiTmp;
            hWindow.viewWindow.genRect2(200.0, 200.0, 30.0 / 180.0 * Math.PI, 60.0, 30.0, ref roi);
            this.template.RoiTmp = roi;
            this.template.RoiTmp.Last().Color = "blue";
        }
        private void toolBtn_run_Click(object sender, EventArgs e)
        {
            GetTemplate();
        }
        private void tsb_delete_Click(object sender, EventArgs e)
        {
            if (template.RoiTmp.Count == 0)
                return;
            var roiTmp = template.RoiTmp;
            var roi = template.RoiTmp;
            hWindow.viewWindow.removeActiveROI(ref roi);
            hWindow.viewWindow.removeActiveROI(ref roiTmp);
        }
        private void btn_save_Click(object sender, EventArgs e)
        {
            Save();
        }
        private void tsb_newTemplate_Click(object sender, EventArgs e)
        {
            if (this.template.RoiTmp.Count == 0)
                return;

            CreateTmplate();
        }
        private void CreateTmplate()
        {
            HImage roiImg = hWindow.Image.CopyImage();
            HImage tmpImg = new HImage();

            //暂时取一个roi
            var tmproi = this.template.RoiTmp.Last();
            if (this.template.Roi.Count > 0)
            {
                //roi抠图
                var roi = this.template.Roi.Last();
                roiImg = roiImg.ReduceDomain(roi.getRegion());
            }

            this.template.Param.MinScore = new HTuple((double)this.num_minScore.Value);                      //最小分数
            this.template.Param.NumMatches = (int)this.num_matchNum.Value;                                              //匹配个数
            this.template.Param.MaxOverlap = (double)this.num_maxOverlap.Value;                                         //重叠部分
            this.template.Param.StartRad = new HTuple(double.Parse(this.num_rad1.Value + ""));                          //角度
            this.template.Param.EndRad = new HTuple(double.Parse(this.num_rad2.Value + ""));                            //角度
            this.template.Param.Polarity = this.cob_jixing.SelectedIndex == 0 ? "use_polarity" : "ignore_global_polarity";  //极性

            //模板抠图
            tmpImg = roiImg.ReduceDomain(tmproi.getRegion());

            //创建模板
            template.hShapeModel = tmpImg.CreateShapeModel("auto",
                 this.template.Param.StartRad,
                 this.template.Param.EndRad,
                 "auto",
                 "auto",
                 this.template.Param.Polarity,
                 "auto",
                 "auto");

            GetTemplate();
        }
        public bool GetTemplate()
        {
            if (this.template == null)
            {
                Log4.Warr($"模板不能为空");
                return false;
            }
            结果 = null;
            bool isSuccess = false;
            HImage image = hWindow.Image.CopyImage();
            if (image == null)
                Log4.Warr($"无图片");

            template.hShapeModel.FindShapeModel(image,
                                        this.template.Param.StartRad,
                                        this.template.Param.EndRad,
                                        this.template.Param.MinScore,
                                        this.template.Param.NumMatches,
                                        this.template.Param.MaxOverlap,
                                        this.template.Param.SubPixel,
                                        this.template.Param.NumLevels,
                                        this.template.Param.Greediness,
                                        out var row,
                                        out var column,
                                        out var angle,
                                        out var score);
            if (row.Length > 0 && column.Length > 0 && angle.Length > 0 && score.Length > 0)
            {
                结果 = new TemplateResultModel()
                {
                    Angle = angle,
                    Column = column,
                    Row = row,
                    Score = score
                };

                //下面为roi区域的中心位置，非模板的中心位置
                HXLDCont xld1 = new HXLDCont();
                xld1.GenCrossContourXld(row, column, 60, new HTuple(0));
                hWindow.DispObj(xld1, "green");

                for (int i = 0; i < score.Length; i++)
                {
                    Log4.Info($"模板匹配:row:{row},column:{column},angle:{angle},score:{score}");
                    //定义仿射变换
                    HHomMat2D hHomMat2D = new HHomMat2D();
                    hHomMat2D.HomMat2dIdentity();
                    hHomMat2D.VectorAngleToRigid(new HTuple(0), new HTuple(0), new HTuple(0), row[i], column[i], angle[i]);
                    //获取轮廓
                    var hxld = template.hShapeModel.GetShapeModelContours(1);
                    //反射变换
                    var contour = hHomMat2D.AffineTransContourXld(hxld);
                    //模板的中心位置
                    contour.AreaCenterPointsXld(out double row1, out var column1);

                    //匹配到的模板中心位置
                    //画x
                    //HXLDCont xld = new HXLDCont();
                    //xld.GenCrossContourXld(row1, column1, 60, new HTuple(45.0));
                    //hWindow.DispObj(xld);
                    //Log4.Info($"模板匹配:轮廓:row:{row1},column:{column1}");
                    hWindow.DispObj(contour, "green");
                }

                isSuccess = true;
            }
            else
                Log4.Warr($"模板匹配:未找到");

            image.Dispose();
            return isSuccess;
        }
        public TemplateResultModel 结果 { get; set; }
    }
}
